package GA_Test;

import 多无人机架次.*;

import java.util.ArrayList;
import java.util.Random;

public class Adaptive_Operate {

    static SpeciesPopulation run(SpeciesPopulation new_list,float now_tem){
        double[] weight = new double[8];
        weight[1] = 1;weight[2] = 1;weight[3] = 1;weight[4] = 1;weight[5] = 1;weight[6] = 1;weight[7] = 1;//算子权重的初始化
        SpeciesPopulation new_pop = new SpeciesPopulation(); //生成一个待完善的种群
        //这里利用轮盘赌去选择使用某个算法
        //选择完算法之后 对算法进行20次循环  选择出最好的个体   根据结果对当前算法的  权重进行调整
        in:for (int i = 0; i < new_list.specPopu.size(); i++) {//拿出一个个体
            SpeciesIndividual now_individual = new_list.specPopu.get(i);//拿出一个旧个体
            double old_runtime = now_individual.individual_runtime;
            SpeciesIndividual copy_old = now_individual.clone(); //对这个拿出来的个体进行克隆
            int select_operator_no = 0;
                double sum_weight = 0;
                for(int k = 1;k<8;k++){
                    sum_weight += weight[k]; //这里是对每个算子当前的权重进行累加
                }
                double select_sum = 0;
                float x = (float) Math.random();//
                for (int j = 1; j < 8; j++) {
                    select_sum += weight[j]/sum_weight;//第j个算子 被选中的概率
                    if (select_sum >= x) {
                        //这个时候就找到了这个满足条件的j 即：第j个算子
                        select_operator_no = j;//这里记录 选择了第几个算子  用于后面对该算子的权重进行调整
                        //利用这个算子对这个个体操作 3次。
                        for(int mmm = 0;mmm<3;mmm++) {
                            Adaptive_Operate.Method(j, now_individual);//3次操作后  返回对这个个体的最好结果
                        }
                        break;
                    }
                }
            //这里利用模拟退火规则去判断是否接受这个新个体
            now_individual.calFitness();
            double new_runtime = now_individual.individual_runtime;
            if (new_runtime <= old_runtime) { //如果新个体的时间优于旧个体 那么就接受新个体
                new_pop.add(now_individual);
                weight[select_operator_no] += 0;
                continue in;//复制完当前这个 更好的个体 继续处理种群内其他个体
            } else { //如果不是的话 利用模拟退火规则接受这个个体
                Random random = new Random();
                double value = Math.exp((new_runtime - old_runtime) / now_tem);
                double r = random.nextInt(1);//生成一个0-1之间的随机数
                if (r > value) {//如果随机生成的概率大于这个 模拟退火的概率值  那么就接受这个劣解
                    new_pop.add(now_individual);
                    weight[select_operator_no] += 0;
                    continue in;
                } else {//这里本来是还原个体 现在不需要还原 因为如果没有发生优化 个体在交叉时就进行了还原 即只要交叉 必定是优化过的
                    new_pop.add(copy_old); //把之前复制的那个备份个体 加进去
                    weight[select_operator_no] += 0;
                    continue in;
                }
            }
        }
//        System.out.print("[1*"+(double) Math.round(weight[1] * 100) / 100+"]");
//        System.out.print("[2*"+(double) Math.round(weight[2] * 100) / 100+"]");
//        System.out.print("[3*："+(double) Math.round(weight[3] * 100) / 100+"]");
//        System.out.print("[4*"+(double) Math.round(weight[4] * 100) / 100+"]");
//        System.out.print("[5*"+(double) Math.round(weight[5] * 100) / 100+"]");
//        System.out.print("[6*"+(double) Math.round(weight[6] * 100) / 100+"]");
//        System.out.println("[7*"+(double) Math.round(weight[7] * 100) / 100+"]");
return new_pop;
    }

    private static SpeciesIndividual Method(int j, SpeciesIndividual now_individual) {

        if(j==1){//1-0
            ArrayList<Object> truck_collection = now_individual.TruckGenes;
            ArrayList<Object> drone_collection = now_individual.DroneGenes;
            if(truck_collection.size()==1){
                return now_individual;
            }
            Integer a1 = 0;
            Integer a2 = 0;
            Random r = new Random();
            while (true){ //从车辆路径里随机选出两个不同的路径
              // System.out.println("85行在循环");
                a1 = r.nextInt(truck_collection.size());
                a2 = r.nextInt(truck_collection.size());
                if(a1 != a2){
                    break;
                }
            }
            //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
            ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
            ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
            ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
            ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
            ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
            ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
            double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
            Random random = new Random();
            for(int i = 0;i<20;i++) {
                if(t1_customers.size()<1){
                    break;
                }
                Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
                //t2中就不选择顾客点了  因为要把 t1选择的顾客加入 t2
                t1_customers.remove(t1_change_point);//移除

                t2_customers.add(t1_change_point); //加入
                Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
                Object[] t2_and_d2 = reProduce(t2_customers);
                ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
                ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
                ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
                ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
                if (truck1.size() == 1 && truck2.size() == 1) {
                    //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                    ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                    ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                    ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                    ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                    truck_collection.set(a1,tt1);
                    drone_collection.set(a1,dd1);
                    truck_collection.set(a2,tt2);
                    drone_collection.set(a2,dd2);
                    double truck1_time = TimeCount.timeCount(tt1,dd1);
                    double truck2_time = TimeCount.timeCount(tt2,dd2);
                    double now_time = truck1_time + truck2_time;  //新路径的时间和
                    if(now_time<best_time){
                        break;
                    }else{
                        continue;
                    }
                } else { //否则的话 继续循环

                    t1_customers.add(t1_change_point);
                    t2_customers.remove(t1_change_point);
                    continue;
                }

            }
            return now_individual;
        }else if (j==2){//1-1
            ArrayList<Object> truck_collection = now_individual.TruckGenes;
            ArrayList<Object> drone_collection = now_individual.DroneGenes;
            if(truck_collection.size()==1){
                return now_individual;
            }
            Integer a1 = 0;
            Integer a2 = 0;
            Random r = new Random();
            while (true){ //从车辆路径里随机选出两个不同的路径
              //  System.out.println("153行在循环");
                a1 = r.nextInt(truck_collection.size());
                a2 = r.nextInt(truck_collection.size());
                if(a1 != a2){
                    break;
                }
            }
            //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
            ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
            ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
            ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
            ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
            ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
            ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
            double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
            Random random = new Random();
            for(int i = 0;i<20;i++) {
                Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
                Integer t2_change_point = t2_customers.get(random.nextInt(t2_customers.size()));

                t1_customers.remove(t1_change_point);
                t1_customers.add(t2_change_point);
                t2_customers.remove(t2_change_point);
                t2_customers.add(t1_change_point); //进行交换
                Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
                Object[] t2_and_d2 = reProduce(t2_customers);
                ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
                ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
                ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
                ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
                if (truck1.size() == 1 && truck2.size() == 1) {
                    //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                    ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                    ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                    ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                    ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                    truck_collection.set(a1,tt1);
                    drone_collection.set(a1,dd1);
                    truck_collection.set(a2,tt2);
                    drone_collection.set(a2,dd2);
                    double truck1_time = TimeCount.timeCount(tt1,dd1);
                    double truck2_time = TimeCount.timeCount(tt2,dd2);
                    double now_time = truck1_time + truck2_time;  //新路径的时间和
                    if(now_time<best_time){
                        break;
                    }else{
                        continue;
                    }
                } else { //否则的话 继续循环
                    t1_customers.remove(t2_change_point);
                    t1_customers.add(t1_change_point);
                    t2_customers.remove(t1_change_point);
                    t2_customers.add(t2_change_point); //进行还原
                    continue;
                }

            }
            return now_individual;
        }else if(j==3){//1-2
            ArrayList<Object> truck_collection = now_individual.TruckGenes;
            ArrayList<Object> drone_collection = now_individual.DroneGenes;
            if(truck_collection.size() == 1){ //这里主要是为了 小规模情况下 会出现只有一辆车的情况  这时候 这个算子不能用只能退出
                return now_individual;
            }
            Integer a1 = 0;
            Integer a2 = 0;
            Random r = new Random();
            while (true){ //从车辆路径里随机选出两个不同的路径
              //  System.out.println("221行在循环");
                a1 = r.nextInt(truck_collection.size());
                a2 = r.nextInt(truck_collection.size());
                if(a1 != a2){
                    ArrayList<Integer> a = (ArrayList<Integer>) truck_collection.get(a1);
                    ArrayList<Integer> b = (ArrayList<Integer>) truck_collection.get(a2);
                    if(a.size()>=2 && b.size()>=1){
                        break;   //这里是因为 当每次交换两个点时   必须保证所获取的 两条路径 里面的节点数目 大于等于2  否则就重新获取
                    }else{
                        continue;
                    }
                }
            }
            //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
            ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
            ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
            ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
            ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
            ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
            ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
            double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
            Random random = new Random();
            for(int i = 0;i<10;i++) {
                if(t1_customers.size()<2){
                    break;
                }
                Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
                t1_customers.remove(t1_change_point);//拿出来 直接删掉

                Integer t1_change_point2 = t1_customers.get(random.nextInt(t1_customers.size()));//再拿一个
                t1_customers.remove(t1_change_point2);//再删掉
                Integer t2_change_point = t2_customers.get(random.nextInt(t2_customers.size())); //对第二辆车执行同样的操作
                t2_customers.remove(t2_change_point);   //从t2里面 只删除一个   把t1中拿出来的两个  放进 t2


                t1_customers.add(t2_change_point);

                t2_customers.add(t1_change_point); t2_customers.add(t1_change_point2);//进行交换
                Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
                Object[] t2_and_d2 = reProduce(t2_customers);
                ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
                ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
                ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
                ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
                if (truck1.size() == 1 && truck2.size() == 1) {
                    //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                    ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                    ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                    ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                    ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                    truck_collection.set(a1,tt1);
                    drone_collection.set(a1,dd1);
                    truck_collection.set(a2,tt2);
                    drone_collection.set(a2,dd2);
                    double truck1_time = TimeCount.timeCount(tt1,dd1);
                    double truck2_time = TimeCount.timeCount(tt2,dd2);
                    double now_time = truck1_time + truck2_time;  //新路径的时间和
                    if(now_time<best_time){
                        break;
                    }else{
                        continue;
                    }
                } else { //否则的话 继续循环

                    t1_customers.remove(t2_change_point);
                    t1_customers.add(t1_change_point);
                    t1_customers.add(t1_change_point2);
                    t2_customers.add(t2_change_point); //进行还原
                    t2_customers.remove(t1_change_point);
                    t2_customers.remove(t1_change_point2);
                    continue;
                }

            }
            return now_individual;
        }else if(j==4){//2-0
            ArrayList<Object> truck_collection = now_individual.TruckGenes;
            ArrayList<Object> drone_collection = now_individual.DroneGenes;
            if(truck_collection.size() == 1){ //这里主要是为了 小规模情况下 会出现只有一辆车的情况  这时候 这个算子不能用只能退出
                return now_individual;
            }
            Integer a1 = 0;
            Integer a2 = 0;
            Random r = new Random();
            while (true){ //从车辆路径里随机选出两个不同的路径
             //   System.out.println("303行在循环");
                a1 = r.nextInt(truck_collection.size());
                a2 = r.nextInt(truck_collection.size());
                if(a1 != a2){
                    ArrayList<Integer> a = (ArrayList<Integer>) truck_collection.get(a1);
                    ArrayList<Integer> b = (ArrayList<Integer>) truck_collection.get(a2);
                    if(a.size()>=2 && b.size()>=0){
                        break;   //这里是因为 当每次交换两个点时   必须保证所获取的 两条路径 里面的节点数目 大于等于2  否则就重新获取
                    }else{
                        continue;
                    }
                }
            }
            //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
            ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
            ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
            ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
            ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
            ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
            ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
            double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
            Random random = new Random();
            for(int i = 0;i<10;i++) {
                if(t1_customers.size()<2){
                    break;
                }
                Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
                t1_customers.remove(t1_change_point);//拿出来 直接删掉

                Integer t1_change_point2 = t1_customers.get(random.nextInt(t1_customers.size()));//再拿一个
                t1_customers.remove(t1_change_point2);//再删掉

                t2_customers.add(t1_change_point); t2_customers.add(t1_change_point2);//进行交换
                Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
                Object[] t2_and_d2 = reProduce(t2_customers);
                ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
                ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
                ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
                ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
                if (truck1.size() == 1 && truck2.size() == 1) {
                    //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                    ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                    ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                    ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                    ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                    truck_collection.set(a1,tt1);
                    drone_collection.set(a1,dd1);
                    truck_collection.set(a2,tt2);
                    drone_collection.set(a2,dd2);
                    double truck1_time = TimeCount.timeCount(tt1,dd1);
                    double truck2_time = TimeCount.timeCount(tt2,dd2);
                    double now_time = truck1_time + truck2_time;  //新路径的时间和
                    if(now_time<best_time){
                        break;
                    }else{
                        continue;
                    }
                } else { //否则的话 继续循环
                    t1_customers.add(t1_change_point);
                    t2_customers.remove(t1_change_point);

                    t1_customers.add(t1_change_point2);
                    t2_customers.remove(t1_change_point2);

                    continue;
                }

            }
            return now_individual;
        }else if(j==5){//2-2
            ArrayList<Object> truck_collection = now_individual.TruckGenes;
            ArrayList<Object> drone_collection = now_individual.DroneGenes;
            if(truck_collection.size() == 1){ //这里主要是为了 小规模情况下 会出现只有一辆车的情况  这时候 这个算子不能用只能退出
                return now_individual;
            }
            Integer a1 = 0;
            Integer a2 = 0;
            Random r = new Random();
            while (true){ //从车辆路径里随机选出两个不同的路径
               // System.out.println("380");
                a1 = r.nextInt(truck_collection.size());
                a2 = r.nextInt(truck_collection.size());
                if(a1 != a2){
                    ArrayList<Integer> a = (ArrayList<Integer>) truck_collection.get(a1);
                    ArrayList<Integer> b = (ArrayList<Integer>) truck_collection.get(a2);
                    if(truck_collection.size()==2){
                        if(a.size()==1||b.size()==1){
                            return now_individual;
                        }
                    }
                    if(a.size()>=2 && b.size()>=2){
                        break;   //这里是因为 当每次交换两个点时   必须保证所获取的 两条路径 里面的节点数目 大于等于2  否则就重新获取
                    }else{
                        continue;
                    }
                }
            }
            //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
            ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
            ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
            ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
            ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
            ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
            ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
            double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
            Random random = new Random();
            for(int i = 0;i<10;i++) {
                Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
                t1_customers.remove(t1_change_point);//拿出来 直接删掉
                if(t1_customers.size()==0){
                    System.out.println("ss");
                }
                Integer t1_change_point2 = t1_customers.get(random.nextInt(t1_customers.size()));//再拿一个
                t1_customers.remove(t1_change_point2);//再删掉
                Integer t2_change_point = t2_customers.get(random.nextInt(t2_customers.size())); //对第二辆车执行同样的操作
                t2_customers.remove(t2_change_point);
                if(t2_customers.size()==0){
                    System.out.println("ss");
                }
                Integer t2_change_point2 = t2_customers.get(random.nextInt(t2_customers.size()));
                t2_customers.remove(t2_change_point2);

                t1_customers.add(t2_change_point);t1_customers.add(t2_change_point2);

                t2_customers.add(t1_change_point); t2_customers.add(t1_change_point2);//进行交换
                Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
                Object[] t2_and_d2 = reProduce(t2_customers);
                ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
                ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
                ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
                ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
                if (truck1.size() == 1 && truck2.size() == 1) {
                    //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                    ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                    ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                    ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                    ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                    truck_collection.set(a1,tt1);
                    drone_collection.set(a1,dd1);
                    truck_collection.set(a2,tt2);
                    drone_collection.set(a2,dd2);
                    double truck1_time = TimeCount.timeCount(tt1,dd1);
                    double truck2_time = TimeCount.timeCount(tt2,dd2);
                    double now_time = truck1_time + truck2_time;  //新路径的时间和
                    if(now_time<best_time){
                        break;
                    }else{
                        continue;
                    }
                } else { //否则的话 继续循环

                    t1_customers.remove(t2_change_point);
                    t1_customers.add(t1_change_point);
                    t2_customers.remove(t1_change_point);
                    t2_customers.add(t2_change_point); //进行还原

                    t1_customers.remove(t2_change_point2);
                    t1_customers.add(t1_change_point2);
                    t2_customers.remove(t1_change_point2);
                    t2_customers.add(t2_change_point2);
                    continue;
                }

            }
            return now_individual;
        }else if(j==6){
            big:for(int k = 0;k<now_individual.TruckGenes.size();k++){ //也别随机选了  就是把每一个车辆路径下的最优找出来
                ArrayList<Integer> truck_route =  (ArrayList<Integer>) now_individual.TruckGenes.get(k);
                ArrayList<Integer> drone_route = (ArrayList<Integer>) now_individual.DroneGenes.get(k);
                if (drone_route.size() != 0) { //不等于0 说明 当前选的这车上面有无人机架次
                    double best = TimeCount.timeCount(truck_route,drone_route);//将当前传进来的这个组合的时间设为最好的
                    ArrayList<Integer> message = new ArrayList<>();
                    for (int t = 0; t < truck_route.size(); t++) {
                        for (int d = 0; d < drone_route.size(); d++) {
                            if (truck_route.get(t) == drone_route.get(d)) {
                                message.add(t);
                                message.add(d);
                                message.add(truck_route.get(t));
                            }
                        }
                    }
                    if(message.size()<6){
                        continue big;
                    }
                    int truck_off1_position = message.get(0); //车辆访问路径中 无人机第一次起飞的位置
                    int drone_off1_position = message.get(1);// 无人机路径中  无人机第一次起飞的位置
                    int off1 = message.get(2);// 起飞的客户点
                    int truck_down1_position = message.get(3);//车辆访问路径中 无人机第一次降落的位置
                    int drone_down1_position = message.get(4);//无人机路径中 无人机第一次降落的位置
                    int down1 = message.get(5);//降落的客户点
                    int truck_off2_position = 0;
                    int drone_off2_position = 0;
                    int off2 = 0;
                    int truck_down2_position = 0;
                    int drone_down2_position = 0;
                    int down2 = 0;
                    if (message.size() > 6) {
                        truck_off2_position = message.get(6);
                        drone_off2_position = message.get(7);
                        off2 = message.get(8);
//            System.out.println(truck_route);
//            System.out.println(drone_route);
//            System.out.println(message);
                        if(message.size() == 9){
                            System.out.println("s");
                        }
                        truck_down2_position = message.get(9);
                        drone_down2_position = message.get(10);
                        down2 = message.get(11);
                    }
                    if (message.size() == 6) {//只有一个架次  单架次用随机撞
                        while(true) {
                         //   System.out.println("506");

                            Random r = new Random();
                            int off = r.nextInt(truck_route.size() - 1);
                            int down = r.nextInt(truck_route.size() );
                            if(down>off){
                                drone_route.set(0,truck_route.get(off));
                                drone_route.set(drone_route.size()-1,truck_route.get(down));
                                break;
                            }else{
                                continue;
                            }
                        }
                    } else { //有两个架次
                        if (truck_down1_position - truck_off1_position > 1) {//更换无人机第一架次的起飞点
                            //把无人机第一架次的起飞点替换成车辆后面一个点
                            ArrayList<Integer> arr1 = new ArrayList<>();
                            for (int i = 0; i < drone_route.size(); i++) {
                                arr1.add(drone_route.get(i));//把当前的无人机路径 给存起来
                            }//把无人机路径赋给 arr1
                            drone_route.set(drone_off1_position, truck_route.get(truck_off1_position + 1)); //更改无人机路径
                            double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                            if (time < best) {
                                best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                                break big;
                            } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                                for (int kk = 0; kk < arr1.size(); kk++) {
                                    drone_route.set(kk, arr1.get(kk));
                                }
                            }
                        }
                        if (truck_off2_position - truck_down1_position > 1) {
                            //把第一架次无人机降落点往后挪一位
                            ArrayList<Integer> arr2 = new ArrayList<>();
                            for (int i = 0; i < drone_route.size(); i++) {
                                arr2.add(drone_route.get(i));//把当前的无人机路径 给存起来
                            }//把无人机路径赋给 arr2
                            drone_route.set(drone_down1_position, truck_route.get(truck_down1_position + 1)); //更改无人机路径
                            double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                            if (time < best) {
                                //best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                                break big; //这样写 就是 一旦在某辆车上 取得了比较好的交换结果  就直接停止
                            } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                                for (int kk = 0; kk < arr2.size(); kk++) {
                                    drone_route.set(kk, arr2.get(kk));
                                }
                            }
                        }
                        if (truck_down2_position - truck_off2_position > 1) {
                            //把第二架次无人机的起飞点往后挪一位
                            ArrayList<Integer> arr = new ArrayList<>();
                            for (int i = 0; i < drone_route.size(); i++) {
                                arr.add(drone_route.get(i));//把当前的无人机路径 给存起来
                            }//把无人机路径赋给 arr2
                            drone_route.set(drone_off2_position, truck_route.get(truck_off2_position + 1)); //交换过程
                            double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                            if (time < best) {
                                best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                            } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                                for (int kk = 0; kk < arr.size(); kk++) {
                                    drone_route.set(kk, arr.get(kk));
                                }
                            }
                        }
                        if (truck_down2_position != truck_route.size() - 1) {
                            //把第二架次无人机的降落点往后挪一位
                            ArrayList<Integer> arr = new ArrayList<>();
                            for (int i = 0; i < drone_route.size(); i++) {
                                arr.add(drone_route.get(i));//把当前的无人机路径 给存起来
                            }//把无人机路径赋给 arr2
                            drone_route.set(drone_down2_position, truck_route.get(truck_down2_position + 1)); //交换过程
                            double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                            //这里加一个约束判断的语句 用来对交换后的 结果进行约束检查
                            if(isok(truck_route,drone_route)==true){
                                if (time < best) {
                                    best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                                    break big;

                                } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                                    for (int h = 0; h < arr.size(); h++) {
                                        drone_route.set(h, arr.get(h));
                                    }
                                }
                            }else {
                                for (int h = 0; h < arr.size(); h++) {
                                    drone_route.set(h, arr.get(h));
                                }
                            }

                        }
                    }
                    break;
                } else { //如果当前车辆上没有无人机架次的话  就继续找另一辆车
                    continue big;
                }
            }
        }else if(j==7){ //这个 算子就交换生成一个可行解就行了
            big:for(int u = 0;u<now_individual.TruckGenes.size();u++){ //也别随机选了  就是把每一个车辆路径下的最优找出来
                ArrayList<Integer> truck_route =  (ArrayList<Integer>) now_individual.TruckGenes.get(u);
                ArrayList<Integer> drone_route = (ArrayList<Integer>) now_individual.DroneGenes.get(u);
                if (drone_route.size() != 0) { //不等于0 说明 当前选的这车上面有无人机架次
                    double best = TimeCount.timeCount(truck_route,drone_route);//将当前传进来的这个组合的时间设为最好的
                    ArrayList<Integer> message = new ArrayList<>();
                    for (int t = 0; t < truck_route.size(); t++) {
                        for (int d = 0; d < drone_route.size(); d++) {
                            if (truck_route.get(t) == drone_route.get(d)) {
                                message.add(t);
                                message.add(d);
                                message.add(truck_route.get(t));
                            }
                        }
                    }
                    if(message.size()<6){ //如果当前  车辆与无人机未够成 有效的架次 则直接退出方法
                        continue big;
                    }
                    int truck_off1_position = message.get(0); //车辆访问路径中 无人机第一次起飞的位置
                    int drone_off1_position = message.get(1);// 无人机路径中  无人机第一次起飞的位置
                    int off1 = message.get(2);// 起飞的客户点
                    int truck_down1_position = message.get(3);//车辆访问路径中 无人机第一次降落的位置
                    int drone_down1_position = message.get(4);//无人机路径中 无人机第一次降落的位置
                    int down1 = message.get(5);//降落的客户点
                    int truck_off2_position = 0;
                    int drone_off2_position = 0;
                    int off2 = 0;
                    int truck_down2_position = 0;
                    int drone_down2_position = 0;
                    int down2 = 0;
                    if (message.size() > 6) {
                        truck_off2_position = message.get(6);
                        drone_off2_position = message.get(7);
                        off2 = message.get(8);
//            System.out.println(truck_route);
//            System.out.println(drone_route);
//            System.out.println(message);
                        if(message.size() == 9){
                            System.out.println("ss");
                        }
                        truck_down2_position = message.get(9);
                        drone_down2_position = message.get(10);
                        down2 = message.get(11);
                    }
                    //把无人机与车辆的访问顾客点分别提取出来


                    //随机从车辆访问顾客中挑一个点，从无人机访问顾客中挑一个点进行交换
                    for(int k = 0;k<10;k++) { //这里的循环是想 多遍历几次交换  取最好的值
                        ArrayList<Integer> truck_service = new ArrayList<>();
                        ArrayList<Integer> drone_service = new ArrayList<>();
                        for(int m = drone_off1_position+1;m<drone_down1_position;m++){
                            drone_service.add(drone_route.get(m));
                        }
                        for(int m = drone_off2_position+1;m<drone_down2_position;m++){
                            drone_service.add(drone_route.get(m));
                        }
                        if(truck_off2_position == 0){//此时说明只有一个架次
                            for(int m = 0;m<truck_off1_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_off1_position+1;m<truck_down1_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_down1_position+1;m<truck_route.size();m++){
                                truck_service.add(truck_route.get(m));
                            }
                        }else{//两个架次的情况
                            for(int m = 0;m<truck_off1_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_off1_position+1;m<truck_down1_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_down1_position+1;m<truck_off2_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_off2_position+1;m<truck_down2_position;m++){
                                truck_service.add(truck_route.get(m));
                            }
                            for(int m = truck_down2_position+1;m<truck_route.size();m++){
                                truck_service.add(truck_route.get(m));
                            }
                        }
                        Random random =  new Random();
                        if(truck_service.size()!=0 && drone_service.size()!=0) {
                            int truck_point = truck_service.get(random.nextInt(truck_service.size()));
                            int truck_point_position = 0;

                            int drone_point = drone_service.get(random.nextInt(drone_service.size()));
                            int drone_point_position = 0;

                            //找到这个车辆节点与无人机节点的所在位置    然后进行对应交换
                            for (int n = 0; n < truck_route.size(); n++) {
                                if (truck_point == truck_route.get(n)) {
                                    truck_point_position = n;
                                }
                            }
                            for (int n = 0; n < drone_route.size(); n++) {
                                if (drone_point == drone_route.get(n)) {
                                    drone_point_position = n;
                                }
                            }

                            truck_route.set(truck_point_position, drone_point);
                            drone_route.set(drone_point_position, truck_point);
                            //这里完成交换 完成后 应当将service 集合中内容清除  根据交换结果 进行重新生成

                            //进行交换后的约束检查
                            if (isok(truck_route, drone_route)) {//如果交换后满足约束
                                double time = TimeCount.timeCount(truck_route, drone_route);//计算交换后的时间
                                if (time < best) {
                                    best = time;
                                    break big;
                                } else {
                                    truck_route.set(truck_point_position, truck_point);
                                    drone_route.set(drone_point_position, drone_point);//交换回去
                                }
                            } else { //不满足约束的话  将车辆路径进行还原 继续进行交换
                                truck_route.set(truck_point_position, truck_point);
                                drone_route.set(drone_point_position, drone_point);//交换完成
                            }
                        }
                    }
                    break big;
                } else { //如果当前车辆上没有无人机架次的话  就继续找另一辆车
                    continue big;
                }
            }
        }
      return now_individual;
    }
    public static Object[] reProduce(ArrayList<Integer> customers) {
        Object[] obj = new Object[2];
        ArrayList<Object> truck_hub = new ArrayList<>(); //车辆行驶路径集合
        ArrayList<Object> drone_hub = new ArrayList<>();//无人机行驶路径集合
        ArrayList<Integer> w = new ArrayList<Integer>();
        double D = GAData.distanceDrone;//无人机续航距离
        int M = GAData.capacityDrone;//无人机载重
        int Q = GAData.capacityTruck;//车辆载重
        for (Integer c = 0; c < customers.size(); c++) { //初始将所有的顾客节点 加入未访问节点集w
            w.add(customers.get(c));//把customers集合中的所有顾客点作为输出  放到所有未访问节点集合w中
        }
        car:
        for (int i = 0; i < 20; i++) {//车辆选择循环
            //初始化w未访问节点集 f已访问节点集 RT车辆访问节点 RU无人机访问节点  dronetrip是当前车辆的无人机线路集
            ArrayList<Object> hub = new ArrayList<>(100);//hub是一个中转的集合  初始的长度设为100
            for (int j = 0; j < 30; j++) {
                hub.add(new ArrayList<Integer>());
            }
            ArrayList<Object> drone_trip = new ArrayList<Object>(100);
            ArrayList<Integer> f = new ArrayList<Integer>();
            ArrayList<Integer> RT = new ArrayList<Integer>();
            ArrayList<Integer> RU = new ArrayList<Integer>();
            int j;double l = 0.00;ArrayList<Integer> s = null;
            if(w.size()>1) {
                //这里不用随机 就用传统的方法去生成车辆路径
                Integer theFirstpoint = Distance.wDistance1(0, w);
                w.remove(theFirstpoint);
                Integer theSecondPoint = Distance.wDistance1(theFirstpoint, w);

                w.remove(theSecondPoint);
                l = GAData.disCollection[theFirstpoint][theSecondPoint];
                //进行对应距离点的 加入与移除操作
                RU.add(theFirstpoint);
                RT.add(theFirstpoint);
                RT.add(theSecondPoint);
                f.add(theFirstpoint);
                f.add(theSecondPoint);
                if(w.size()==0){
                    PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                    //sum_time += time;
                    break car;
                }
                s = Distance.sProduce(w, RU);// 获取s
                //如果 s 没有获取成功   并且 w中只有一个数  那么说明当前w中这个数 不满足某约束  则将其加入RT中 打印输出
                if(s.size()==0 && w.size()==1){
                    RT.add(w.get(0));
                    PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                    //sum_time += time;
                    break car;
                }
            }else if(w.size()==1){
                RT.add(w.get(0));
                PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                //sum_time += time;
                break car;
            }else if(w.size()==0){
                break car;
            }
            sdrone:
            for (j = 0; j < s.size(); j++) {
                RU.add(s.get(j));
                w.remove(s.get(j));
                f.add(s.get(j));
                double Ud = Distance.sumUd(RU);
                int Uzz = Capcity.Uzz(RU);
                int rucount = RU.size();
                //******************************************************************************距离判断分支 2
                if (Ud >= D && rucount == 2) {

                    Integer ru_last = RU.get(RU.size() - 1);
                    Integer rt_last = RT.get(RU.size() - 1);
                    w.add(ru_last);
                    f.remove(ru_last);
                    RU.clear();
                    RU.add(RT.get(RT.size() - 1));
                    Integer w_closest = Distance.wDistance1(rt_last, w);
                    RT.add(w_closest);
                    l = GAData.disCollection[rt_last][w_closest];
                    w.remove(w_closest);
                    f.add(w_closest);
                    int f_demand = Capcity.fD(f);//已访问节点中 的需求

                    if (f_demand < Q) {
                        if (w.size() > 0) {
                            s = Distance.sProduce(w, RU);
                            if(s.size()==0 && w.size()==1){//这个判断比较关键   决定的是 所剩下的 未访问节点 均无法再被无人机访问的情况
                                RT.add(w.get(0));
                                PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }
                            j = -1;//从0 开始 遍历新的s
                            continue sdrone;
                        } else {
                            PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                    } else if (f_demand == Q) {//需要换辆车
                        if (w.size() > 0) {

                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(w.size()==1){
                                int k = 0;
                            }
                            continue car;
                        } else {
                            PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                    } else if (f_demand > Q) {
                        RT.remove(RT.get(RT.size() - 1));
                        w.add(RT.get(RT.size() - 1));
                        f.remove(RT.get(RT.size() - 1));
                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        if(w.size()==1){
                            int k = 0;
                        }
                        continue car;
                    }
                    //**********************************************************************距离判断分支 1
                } else if (Ud == D && rucount > 2) {
                    RT.add(RU.get(RU.size() - 1));  //将RU内最后一个点加入RT
                    drone_trip = DroneTripUpdate.Method(hub, RU); //将当前RU存在 drone trip里
                    RU.clear();
                    //寻找未访问节点集w中距离RT内最后一个点 距离最近的两个点，并加入RT 纠正错误：应该是最近的一个点  与 当前这个最近点 最近的点
                    if (w.size() > 1) {
                        Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                        RT.add(the_closest);w.remove(the_closest);
                        Integer the_second = Distance.wDistance1(the_closest, w);
                        RT.add(the_second);w.remove(the_second);
                        //将RU内的节点清除掉   并将上述theclosest点 加入RU内 作为新的起飞点
                        RU.add(the_closest);
                        f.add(the_closest);
                        f.add(the_second);
                        l = GAData.disCollection[the_closest][the_second];
                        //下列为 一模一样的步骤
                        int f_demand = Capcity.fD(f);//已访问节点中 的需求
                        if (f_demand < Q) {
                            if (w.size() > 0) {
                                s = Distance.sProduce(w, RU);
                                j = -1;
                                continue sdrone;
                            } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                if(RT.size()==1){
                                    Integer kkk=1;
                                }
                                break car;
                            }

                        } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(RT.size()==1){
                                int k =0;
                            }
                            continue car;
                        } else {
                            RT.remove(the_closest);
                            RT.remove(the_second);
                            w.add(the_closest);
                            w.add(the_second);
                            f.add(the_closest);
                            f.add(the_second);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(w.size()==1){
                                int k = 0;
                            }
                            continue car;
                        }
                    } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                        PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                        break car;// 跳出大循环
                    } else if (w.size() == 1) {
                        PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;
                    }
                    //********************************************************距离判断分支3
                } else if (Ud > D && rucount > 3) {//
                    RT.add(RU.get(RU.size() - 2));//将RU中倒数第二个点加入RT
                    w.add(RU.get(RU.size() - 1));
                    f.remove(RU.get(RU.size() - 1));//f 与 w 一增一减
                    RU.remove(RU.size() - 1);
                    drone_trip = DroneTripUpdate.Method(hub, RU);
                    RU.clear();// 保存完 RU后  将 RU清空
                    //********************************************************************
                    if (w.size() > 1) {

                        Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                        RT.add(the_closest);w.remove(the_closest);
                        Integer the_second = Distance.wDistance1(the_closest, w);
                        RT.add(the_second);w.remove(the_second);

                        RU.add(the_closest);//为下一个架次 设置起飞点
                        f.add(the_closest);
                        f.add(the_second);
                        l = GAData.disCollection[the_closest][the_second];
                        int f_demand = Capcity.fD(f);//已访问节点中 的需求

                        if (f_demand < Q) {
                            if (w.size() > 0) {
                                s = Distance.sProduce(w, RU);
                                j = -1;
                                continue sdrone;
                            } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                continue car;
                            }

                        } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(w.size()==1){
                                int k = 0;
                            }
                            continue car;
                        } else {
                            RT.remove(the_closest);
                            RT.remove(the_second);
                            w.add(the_closest);
                            w.add(the_second);
                            f.add(the_closest);
                            f.add(the_second);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(w.size()==1){
                                int k = 0;
                            }
                            continue car;
                        }
                    } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                        PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;// 跳出大循环
                    } else if (w.size() == 1) {
                        PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;
                    }
                } else if (Ud > D && rucount == 3) {
                    Integer ru_last = RU.get(RU.size() - 1);
                    Integer ru_second = RU.get(RU.size() - 2);
                    RU.clear();
                    w.add(ru_last);
                    w.add(ru_second);
                    f.remove(ru_last);
                    f.remove(ru_second);
                    Integer rt_last = RT.get(RT.size() - 1);
                    RU.add(rt_last);//将rt内最后一个点设为ru中的新的起飞点
                    Integer w_closest = Distance.wDistance1(rt_last, w);
                    RT.add(w_closest);
                    l = GAData.disCollection[rt_last][w_closest];
                    w.remove(w_closest);
                    f.add(w_closest);

                    int f_demand = Capcity.fD(f);//已访问节点中 的需求
                    if (f_demand < Q) {
                        if (w.size() > 0) {
                            s = Distance.sProduce(w, RU);
                            j = -1;//从0 开始 遍历新的s
                            continue sdrone;
                        } else {
                            PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                    } else if (f_demand == Q) {
                        if (w.size() > 0) {
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            continue car;
                        } else {
                            PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                    } else if (f_demand > Q) {
                        RT.remove(RT.get(RT.size() - 1));
                        w.add(RT.get(RT.size() - 1));
                        f.remove(RT.get(RT.size() - 1));
                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        continue car;
                    }

                } else if (Ud < D && Uzz == M && rucount > 2) {
                    //************************************************************载重判断分支1
                    RT.add(RU.get(RU.size() - 1));  //将RU内最后一个点加入RT
                    drone_trip = DroneTripUpdate.Method(hub, RU); //将当前RU存在 drone trip里
                    RU.clear();
                    //寻找未访问节点集w中距离RT内最后一个点 距离最近的两个点，并加入RT
                    if (w.size() > 1) {
                        Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                        RT.add(the_closest);w.remove(the_closest);
                        Integer the_second = Distance.wDistance1(the_closest, w);
                        RT.add(the_second);w.remove(the_second);
                        //将RU内的节点清除掉   并将上述theclosest点 加入RU内 作为新的起飞点
                        RU.add(the_closest);
                        //更新w 与 f   更新 l
                        f.add(the_closest);
                        f.add(the_second);
                        l = GAData.disCollection[the_closest][the_second];
                        //下列为 一模一样的步骤
                        int f_demand = Capcity.fD(f);//已访问节点中 的需求
                        if (f_demand < Q) {
                            if (w.size() > 0) {
                                s = Distance.sProduce(w, RU);
                                j = -1;
                                continue sdrone;
                            } else {
                                PrintRoute.printRoute_w0(RT, RU, w,drone_trip,obj,truck_hub,drone_hub);

                            }

                        } else if (f_demand == Q) {
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            continue car;
                        } else {
                            RT.remove(the_closest);
                            RT.remove(the_second);
                            w.add(the_closest);
                            w.add(the_second);
                            f.add(the_closest);
                            f.add(the_second);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            continue car;
                        }
                        w.add(RT.get(RT.size() - 1));
                        f.remove(RT.get(RT.size() - 1));
                        RT.remove(RT.size() - 1);
                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        continue car;
                    } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                        PrintRoute.printRoute_w0(RT, RU, w,drone_trip,obj,truck_hub,drone_hub);
                        break car;// 跳出大循环
                    } else if (w.size() == 1) {
                        PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        break car;
                    }
                } else if (Ud < D && Uzz > M && rucount > 2) {
                    //*********************************************************载重判断分支3
                    RT.add(RU.get(RU.size() - 1));//将RU中倒数第一个点加入RT
                    drone_trip = DroneTripUpdate.Method(hub, RU);
                    RU.clear();// 保存完 RU后  将 RU清空
                    //********************************************************************
                    if (w.size() > 1) {

                        Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                        RT.add(the_closest);w.remove(the_closest);
                        Integer the_second = Distance.wDistance1(the_closest, w);
                        RT.add(the_second);w.remove(the_second);

                        RU.add(the_closest);//为下一个架次 设置起飞点
                        f.add(the_closest);
                        f.add(the_second);
                        l =GAData.disCollection[the_closest][the_second];

                        int f_demand = Capcity.fD(f);//已访问节点中 的需求

                        if (f_demand < Q) {
                            if (w.size() > 0) {
                                s = Distance.sProduce(w, RU);
                                j = -1;
                                continue sdrone;
                            } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }

                        } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            continue car;
                        } else {
                            RT.remove(the_closest);
                            RT.remove(the_second);
                            w.add(the_closest);
                            w.add(the_second);
                            f.add(the_closest);
                            f.add(the_second);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            if(w.size()==1){
                                int k = 0;
                            }
                            continue car;
                        }
                    } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                        PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;// 跳出大循环
                    } else if (w.size() == 1) {
                        PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;
                    }

                }else if(Ud<D && Uzz>=M && rucount==2) {//如果无人机路径里 只有两个点但是 载重已经超负荷
                    RT.add(RU.get(1));//把这个点 送给 车
                    RU.remove(1);//从无人机中移除
                    if(w.size()>0){
                        s = Distance.sProduce(w, RU);//重新生成 s
                        j=-1;
                        continue sdrone;//重新为无人机寻找 客户点
                    }else{
                        PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                        break car;
                    }

                }else if (Ud < D && Uzz < M && Ud >= 1.5 * l) {
                    //*****************************************************1.5l判断 分支 1
                    if (w.size() > 0) {  // 如果未访问的节点数目大于1
                        Integer rt_last = RT.get(RT.size() - 1);
                        Integer rt_last_closest = Distance.wDistance1(rt_last, w);
                        RT.add(rt_last_closest);
                        w.remove(rt_last_closest);
                        f.add(rt_last_closest);
                        l = GAData.disCollection[rt_last][rt_last_closest];//当前RU内起飞点为起点
                        //下列为 一模一样的步骤

                        int f_demand = Capcity.fD(f);//已访问节点中 的需求
                        if (f_demand < Q) {
                            if (w.size() > 0) {
                                s = Distance.sProduce(w, RU);
                                j = -1;//从0 开始 遍历新的s
                                continue sdrone;
                            } else { //w.size == 0
                                if(RU.size()==1){
                                    PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub); //sum_time += time;
                                    break car;
                                }else if(RU.size()==2){
                                    RU.add(RT.get(RT.size()-1));
                                    drone_trip = DroneTripUpdate.Method(hub, RU);
                                    PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }else if(RU.size()>=3){
                                    RT.add(RU.get(RU.size()-1));//将RU内最后一个节点作为降落点
                                    drone_trip = DroneTripUpdate.Method(hub, RU);//
                                    PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }
                            }
                        } else if (f_demand == Q) {
                            if (w.size() > 0) {
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                continue car;
                            } else { //否则应该判断一下 RU中的节点数目

                                PrintRoute.printRoute_w0(RT, RU,w,drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }
                        } else if (f_demand > Q) {
                            Integer rt__last = RT.get(RT.size() - 1);
                            RT.remove(rt__last);
                            w.add(rt__last);
                            f.remove(rt__last);
                            RU.add(RT.get(RT.size()-1));
                            drone_trip = DroneTripUpdate.Method(hub, RU);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;

                            continue car;
                        }
                    } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                        PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;// 跳出大循环
                    }
                } else if (Ud < D && Uzz < M && Ud < 1.5 * l) {//当选择s中数时  选完一个数需要判断w中节点数 、 f_demand与Q的关系
                    if (w.size() == 0) {
                        PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);  //sum_time += time;
                        break car;
                    } else if (w.size() > 0) {
                        int f_demand = Capcity.fD(f);
                        if (f_demand < Q) {
                            continue sdrone;//当 w中仍有节点且 当前访问节点需求 小于 车辆载重  则继续
                        } else {
                            w.add(RU.get(RU.size() - 1));
                            f.remove(RU.get(RU.size() - 1));
                            RU.remove(RU.size() - 1);
                            PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub); //sum_time += time;
                            continue car;
                        }
                    }

                }
            }
        }
        obj[0] = truck_hub;obj[1] = drone_hub;
        return obj;
    }

    private static ArrayList<Integer> getCustomers(ArrayList<Integer> t1, ArrayList<Integer> d1) {
        //此方法用于提取出t1 和 d1 中所有服务的顾客   写到一个集合里  去个重就可以了
        ArrayList<Integer> al = new ArrayList<>();
        for(int i = 0;i<t1.size();i++) {
            if (!al.contains(t1.get(i))){
                al.add(t1.get(i));
            }
        }
        for(int i = 0;i<d1.size();i++){
            if(!al.contains(d1.get(i))){
                al.add(d1.get(i));
            }
        }
        return al;
    }
    private static boolean isok(ArrayList<Integer> truck, ArrayList<Integer> drone) {
        boolean flag = true;
        ArrayList<Integer> off_down_points = new ArrayList<>();
        for(int i = 0;i<drone.size();i++){
            if(truck.contains(drone.get(i))){
                off_down_points.add(drone.get(i));
            }
        }
        if(off_down_points.size() % 2 != 0 ){ //如果这个存起降点的 集合里面不是复数的话 就把最后一个点给去掉
            off_down_points.remove(off_down_points.size()-1);
        }
        //到这里相当于是记录了 无人机的所有起降点
        double drone_distance = 0;
        int drone_cap = 0;
        for(int k = 0;k<off_down_points.size();k++){
            int str = drone.indexOf(off_down_points.get(k));
            int end = drone.indexOf(off_down_points.get(k+1));
            for(int m = str;m<end;m++){
                drone_distance += GAData.disCollection[drone.get(m)][drone.get(m+1)];
            }
            for(int m = str+1;m<end;m++){
                drone_cap += GAData.cusInfo[m].demand;
            }
            if(drone_distance >GAData.distanceDrone || drone_cap> GAData.capacityDrone){
                flag = false;
                break;
            }
            k++;

        }
//        ArrayList<Integer> message = new ArrayList<>();
//        for (int t = 0; t < truck.size(); t++) {
//            for (int d = 0; d < drone.size(); d++) {
//                if (truck.get(t) == drone.get(d)) {
//                    message.add(t);
//                    message.add(d);
//                    message.add(truck.get(t));
//                }
//            }
//        }
//        int truck_off1_position = message.get(0); //车辆访问路径中 无人机第一次起飞的位置
//        int drone_off1_position = message.get(1);// 无人机路径中  无人机第一次起飞的位置
//        int off1 = message.get(2);// 起飞的客户点
//
//        int truck_down1_position = message.get(3);//车辆访问路径中 无人机第一次降落的位置
//        int drone_down1_position = message.get(4);//无人机路径中 无人机第一次降落的位置
//        int down1 = message.get(5);//降落的客户点
//        int truck_off2_position = 0;
//        int drone_off2_position = 0;
//        int off2 = 0;
//        int truck_down2_position = 0;
//        int drone_down2_position = 0;
//        int down2 = 0;
//        if (message.size() > 6) {
//            truck_off2_position = message.get(6);
//            drone_off2_position = message.get(7);
//            off2 = message.get(8);
//            truck_down2_position = message.get(9);
//            drone_down2_position = message.get(10);
//            down2 = message.get(11);
//        }
//        double drone_distance1 =0; int cap1 = 0;
//        double drone_distance2 =0; int cap2 = 0;
//        for(int k =drone_off1_position;k<drone_down1_position;k++){
//            drone_distance1 += GAData.disCollection[drone.get(k)][drone.get(k+1)]; //无人机第一架次距离计算
//        }
//        for(int k = drone_off1_position+1;k<drone_down1_position;k++){//无人机第一架次载重计算
//            cap1 += GAData.cusInfo[k].demand;
//        }
//        if(drone_distance1> GAData.distanceDrone || cap1>GAData.capacityDrone){
//            flag = false;
//        }
//        if(drone_off2_position!=0){
//            for(int k =drone_off2_position;k<drone_down2_position;k++){
//                drone_distance2 += GAData.disCollection[drone.get(k)][drone.get(k+1)]; //无人机第一架次距离计算
//            }
//            for(int k = drone_off2_position+1;k<drone_down2_position;k++){//无人机第二架次载重计算
//                cap2 += GAData.cusInfo[k].demand;
//            }
//        }
//        if(drone_distance2>GAData.distanceDrone || cap2> GAData.capacityDrone){
//            flag = false;
//        }
        return flag;
    }
}
